/*
 * Copyright (C) 2009 Rob Cash
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ScheduleUtils.java
 * 
 * Created on Jan 20, 2009 at 10:36:21 AM
 */

package org.robcash.apps.messagepopup.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
import org.robcash.apps.messagepopup.Main;
import org.robcash.apps.messagepopup.vo.Schedule;

/**
 *
 * @author Rob
 */
public class ScheduleUtils {

    private static final int HALF_HOUR = 30;
    private static final int HOUR = 60;
    private static final int DAY = 1440;
    private static final String TIME = "occurance.once";
    private static final String TIMES = "occurance.multiple";
    private static final String MINUTE_TEXT = "period.minute";
    private static final String MINUTES_TEXT = "period.minutes";
    private static final String HALF_HOUR_TEXT = "period.halfHour";
    private static final String HOUR_TEXT = "period.hour";
    private static final String HOURS_TEXT = "period.hours";
    private static final String DAY_TEXT = "period.day";
    private static final String EVERY_DAY = "day.everyday";
    private static final String WEEKDAYS = "day.weekdays";
    private static final String SUNDAY = "day.sunday";
    private static final String MONDAY = "day.monday";
    private static final String TUESDAY = "day.tuesday";
    private static final String WEDNESDAY = "day.wednesday";
    private static final String THURSDAY = "day.thursday";
    private static final String FRIDAY = "day.friday";
    private static final String SATURDAY = "day.saturday";
    private static final String AND_TEXT = "text.and";
    private static final String EVERY_TEXT = "text.every";
    private static final String ON_TEXT = "text.on";
    private static final String BETWEEN_TEXT = "text.between";

    /**
     * Translate schedule to text
     */
    public static String scheduleToText(Schedule schedule) {
        StringBuilder buf = new StringBuilder();
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleUtils.class);
        buf.append(ScheduleUtils.frequencyToText(schedule.getFrequency()));
        buf.append(" ");
        buf.append(resourceMap.getString(EVERY_TEXT));
        buf.append(" ");
        buf.append(ScheduleUtils.periodToText(schedule.getPeriod()));
        buf.append(" ");
        buf.append(resourceMap.getString(ON_TEXT));
        buf.append(" ");
        buf.append(ScheduleUtils.daysToText(schedule.getDays()));
        buf.append(" ");
        buf.append(resourceMap.getString(BETWEEN_TEXT));
        buf.append(" ");
        buf.append(ScheduleUtils.hoursToText(schedule.getStartTime(),
                schedule.getEndTime()));

        return buf.toString();
    }

    /**
     * Translate frequency
     * @param frequency
     * @return Textual representation of frequency
     */
    public static String frequencyToText(int frequency) {
        StringBuilder buf = new StringBuilder();
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleUtils.class);
        buf.append(frequency);
        buf.append(" ");
        if ( frequency == 1 ) {
            buf.append(resourceMap.getString(TIME));
        }
        else {
            buf.append(resourceMap.getString(TIMES));
        }

        return buf.toString();
    }

    /**
     * Translate days
     * @param days
     * @return Textual representation of days (e.g. weekdays or Sunday and Friday)
     */
    public static String daysToText(Set<Integer> days) {
        StringBuilder buf = new StringBuilder();
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleUtils.class);
        if ( Schedule.EVERY_DAY.equals(days) ) {
            buf.append(resourceMap.getString(EVERY_DAY));
        }
        else if ( Schedule.WEEKDAYS.equals(days) ) {
            buf.append(resourceMap.getString(WEEKDAYS));
        }
        else {
            int numberOfDays = days.size();
            int daysWritten = 0;
            if ( days.contains(Schedule.SUNDAY) ) {
                buf.append(resourceMap.getString(SUNDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.MONDAY) ) {
                buf.append(resourceMap.getString(MONDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.TUESDAY) ) {
                buf.append(resourceMap.getString(TUESDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.WEDNESDAY) ) {
                buf.append(resourceMap.getString(WEDNESDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.THURSDAY) ) {
                buf.append(resourceMap.getString(THURSDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.FRIDAY) ) {
                buf.append(resourceMap.getString(FRIDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }

            if ( days.contains(Schedule.SATURDAY) ) {
                buf.append(resourceMap.getString(SATURDAY));
                daysWritten++;
                addAndToList(buf, daysWritten, numberOfDays);
            }
        }

        return buf.toString();
    }

    private static void addAndToList(StringBuilder buf, int itemsWritten,
            int totalItems) {
        if ( itemsWritten <= totalItems - 2 ) {
            // There are 2 or more days after this
            buf.append(", ");
        }
        else if ( itemsWritten <= totalItems - 1 ) {
            boolean commaAndNeeded = totalItems > 2;
            if ( commaAndNeeded ) {
                buf.append(", ");
            }
            buf.append(AND_TEXT);
            buf.append(" ");
        }
    }

    /**
     * Translate minutes into a text string
     * @param minutes
     * @return Textual representation of minutes (e.g. 1 hour)
     */
    public static String periodToText(int minutes) {
        StringBuilder buf = new StringBuilder();
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleUtils.class);
        if ( minutes < HOUR ) {
            if ( minutes == HALF_HOUR ) {
                buf.append(resourceMap.getString(HALF_HOUR_TEXT));
            }
            else if ( minutes > 1 ) {
                buf.append(minutes);
                buf.append(" ");
                buf.append(resourceMap.getString(MINUTES_TEXT));
            }
            else {
                buf.append(resourceMap.getString(MINUTE_TEXT));
            }
        }
        else if ( minutes < DAY ) {
            int hours = minutes / HOUR;
            int leftOverMinutes = minutes % HOUR;
            if ( hours > 1 || leftOverMinutes > 0 ) {
                buf.append(hours);
                buf.append(" ");
                if ( hours == 1 ) {
                    buf.append(resourceMap.getString(HOUR_TEXT));
                }
                else {
                    buf.append(resourceMap.getString(HOURS_TEXT));
                }
                if ( leftOverMinutes > 0 ) {
                    buf.append(" ");
                    buf.append(resourceMap.getString(AND_TEXT));
                    buf.append(" ");
                    buf.append(leftOverMinutes);
                    buf.append(" ");
                    if ( leftOverMinutes > 1 ) {
                        buf.append(resourceMap.getString(MINUTES_TEXT));
                    }
                    else {
                        buf.append(resourceMap.getString(MINUTE_TEXT));
                    }
                }
            }
            else {
                buf.append(resourceMap.getString(HOUR_TEXT));
            }
        }
        else {
            buf.append(resourceMap.getString(DAY_TEXT));
        }

        return buf.toString();
    }

    /**
     * Translate hours into text
     * @param startTime Start time
     * @param endTime End time
     * @return Textual representation of hours
     */
    public static String hoursToText(Date startTime, Date endTime) {
        StringBuilder buf = new StringBuilder();
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleUtils.class);
        SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
        buf.append(formatter.format(startTime));
        buf.append(" ");
        buf.append(resourceMap.getString(AND_TEXT));
        buf.append(" ");
        buf.append(formatter.format(endTime));

        return buf.toString();
    }
}
